<h2>Tutorial 3: Build a Multiagent Simulation</h2>

<p>In this tutorial we will build a simple model of particles bouncing off walls, leaving trails, and interacting with one another.

<p>This tutorial teaches:
<ul>
<li> How to use the random number generator
<li> More on how to use the Schedule
<li> How to use a Sparse Grid field
<li> How to use a basic field function
<li> About Orderings
<li> About Int2Ds and Bags
<li> How to specify a SimplePortrayal for an object
<li> How to use multiple fields in the same Display
<li> About Serial Versioning and its use in checkpointing
</ul>

<h2>Create a Basic Model</h2>

<p>We'll start with a basic Model.  In the <b>sim/app/tutorial3</b> application directory reate a file called <b>Tutorial3.java</b>.  Add to it:

<pre><tt>
package sim.app.tutorial3;
import sim.engine.*;
import sim.field.grid.*;
import sim.util.*;
import ec.util.*;

public class Tutorial3 extends SimState
    {
    private static final long serialVersionUID = 1;

    public DoubleGrid2D trails;
    public SparseGrid2D particles;
    
    public int gridWidth = 100;
    public int gridHeight = 100;
    public int numParticles = 500;
    
    public Tutorial3(long seed)
        {
        super(seed);
        }

    public void start()
        {
        super.start();
        trails = new DoubleGrid2D(gridWidth, gridHeight);
        particles = new SparseGrid2D(gridWidth, gridHeight);
</tt></pre>

<p><table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1"><b>Wherever did you get such a phenominal implementation of Mersenne Twister?</b>
<p>Thank you!  This implementation is believed to be the fastest Java version available anywhere, and is used fairly widely.  And its author &mdash; who also wrote this tutorial &mdash; is understandably proud of it. :-)  And yes, there's a synchronized java.util.Random subclass version available, though not in the MASON distribution...
</table>
Let's start with the random number generator.  MASON uses an implementation of the <b>Mersenne Twister</b> random number genenerator algorithm called <tt>ec.util.<b>MersenneTwisterFast</b></tt>.  This generator is <i>far</i> more random than the Java-standard generator, <tt>java.util.<b>Random</b></tt>, and it has a <i>massive</i> &mdash; for all intents and purposes infinite &mdash; generation period.  You should never use java.util.Random for real simulation work: it's very bad.  The provided Java implementation of Mersenne Twister, which isn't synchronized, is also about 1.5 times the speed of Java's standard generator.

<p>The MersenneTwisterFast instance we created is stored in the instance variable <b>random</b>.  Don't worry about having to learn a new class: MersenneTwisterFast has an identical API to java.util.Random.  Just call it like you've always done (for example, <tt>random.nextInt(5);</tt> to get a random integer from 0 to 4 inclusive).  But keep in mind that MersenneTwisterFast isn't threadsafe.

<table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>Is there a 2 Dimensional Grid of Objects like DoubleGrid2D is for doubles?</b>
<p>Yes.  It's called <b>ObjectGrid2D</b>, and it works just like DoubleGrid2D and IntGrid2D.  It differs from SparseGrid2D in important ways: first, ObjectGrid2D allows one, and exactly one, object per array location (it's just a wrapper for an Object[][] array).  SparseGrid2D uses hash tables rather than arrays, and allows many objects to pile up on the same array location.  Also, SparseGrid2D is much faster at looking up the location of an object, and is much more memory efficient, but looking up objects at locations is slower (a constant hash table lookup overhead).  Generally speaking, if you need an array of Objects, use ObjectGrid2D.  If you want a few agents scattered in different locations (possibly the same locations), use SparseGrid2D.</font></td></tr></table>
<P>Also, note the declaration of a <b>SparseGrid2D</b> and <b>DoubleGrid2D</b>.  Previously we used an <b>IntGrid2D</b>, which was little more than a wrapper for a two dimensional array of integers.  Likewise, a DoubleGrid2D wraps a two dimensional array of doubles.

<p>SparseGrid2D is a different beast.  It's not an array of objects: instead it uses hash tables internally, and allows you to put an Object at a given location.  Multiple objects may occupy the same location in a SparseGrid2D.

<p>In this tutorial, we're going to make a class called <b>Particle</b>, which is an agent that bounces around the environment.  Particles will be stored in the SparseGrid2D and will leave "trails" in the DoubleGrid2D.  Particles will have a <i>direction</i> (x and y values of 0, 1, or -1 each).  Particles will be <b>embodied agents</b> (they're both agents -- they're Steppable and manipulate the world ; and they're also <i>in</i> the world).  

<p>Let's make <tt>numParticles</tt> Particles, put them in the world at random locations, given them random directions, and schedule them to be fired as Steppables at every time step.  Add:

<pre><tt>
        Particle p;
        for(int i=0 ; i &lt; numParticles ; i++)
            {
            p = new Particle(random.nextInt(3) - 1, random.nextInt(3) - 1);  <font color=gray>// random direction</font>
            schedule.scheduleRepeating(p);
            particles.setObjectLocation(p,
                new Int2D(random.nextInt(gridWidth),random.nextInt(gridHeight)));  <font color=gray>// random location</font>
            }
</tt></pre>

<table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>Why not use java.awt.Point?</b>
<p>Point is mutable.  So are java.awt.geom.Point2D, etc.  But SparseGrid2D uses hashtables.  Mutable objects break hashtables: put the location in the hash table as a key, then change the values in the location.  Instant broken hashtable.  This is a serious Java flaw that Sun has not said much about.</font></td></tr></table>

<p>Note the use of <b>Int2D</b>.  This class is essentially the same as <b>java.awt.Point</b>: it holds an x and a y location as ints.  However, <b>Int2D</b> is <i>immutable</i> -- once it is constructed, its values cannot be changed.  SparseGrid2D stores locations as Int2D.  Likewise, <b>SparseGrid3D</b> stores locations as <b>Int3D</b>, and other fields use <b>Double2D</b> or <b>Double3D</b>.

<p><br clear="both">
<p><table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>I'm not used to code like this.  Can you really make a Steppable class like that?</b>

<P>Sure you can.  It's called an <b>anonymous class</b>, and it's a construct for creating one-shot classes which exist solely to provide an instance of some superclass or interface.  Without it, you'd need to write something like:

<pre><tt>
package sim.app.tutorial3;
import sim.field.grid.*;
import sim.engine.*;
public class MyDecreaser implements Steppable
	{
        private static final long serialVersionUID = 1;

	DoubleGrid2D myTrails;
	public MyDecreaser(DoubleGrid2D tr)
		{
		myTrails = tr;
		}

	public void step(SimState state)
		{
		trails.multiply(0.9);
		}
	}
</tt></pre>

And then say... 
<pre><tt>
Steppable decreaser = new MyDecreaser(trails);
schedule.scheduleRepeating(Schedule.EPOCH,2,decreaser,1);
</tt></pre>

<p>That's an awful lot of typing just for scheduling a Steppable which calls a single function!  Instead, an anonymous class makes for simpler code.  Plus note that inside the anonymous class we can directly access the <b>trails</b> variable, so we don't have to make some complicated constructor nonsense like in the example above.  This is the approximate equivalent to what's known, in modern languages, as a <b>closure</b>.

<p>Note though that in Java we can only reference <b>trails</b> like this if it's an outer instance variable or is a final local variable.  And we have some versioning issues in using anonymous classes, which may or may not mattter to you, as is discussed further below. 
</font></table>

As the agents traverse the world, they will leave trails by setting DoubleGrid2D locations to 1.0.  Let's also create a "decreaser" agent which slowly decreases the DoubleGrid2D values.  

<pre><tt>
        <font color=gray>// Schedule the decreaser</font>
        Steppable decreaser = new Steppable()
            {
            private static final long serialVersionUID = 1;

            public void step(SimState state)
                {
                <font color=gray>// decrease the trails</font>
                trails.multiply(0.9);
</tt></pre>

<p>The <b>multiply</b> function is a simple mapper which multiplies all values in the 2D array by 0.9.  There are other simple functions like that so you don't have to do the for-loops yourself.  Continuing...

<pre><tt>
                }
            };
        schedule.scheduleRepeating(
            Schedule.EPOCH,2,decreaser,1);
        }
</tt></pre>

<p>Notice that we're scheduling the decreaser in a different fashion than before.  This time we're providing four pieces of information:

<ul>
<li><b><tt>Schedule.EPOCH</tt></b>  This is the first time the item will be stepped.  <tt>Schedule.EPOCH</tt> (which is <tt>0.0</tt>) is the earliest possible timestep in the simulation; and it's the default value anyway.
<li><b><tt>2</tt></b>  This is the item's <i>ordering</i>.  See below.
<li><b><tt>decreaser</tt></b> This is the steppable to be scheduled repeating.
<li><b><tt>1</tt></b> This is the interval between repeated steps.  It can be a floating-point value also.
</ul>

<p>An <b>ordering</b> is a sub-ordering of a timestep.  Let's say you have ten items you want to occur at timestep 10.4321121.  But you want five of those items to be stepped before the other five.  You can do this by scheduling the first five for one ordering, and the second five for a higher ordering.  The default ordering is 0.  Within an ordering, the order of agents' firing is random.

<p>What's the point of orderings?  A variety of items occur every time the schedule steps a single timestep.  For example, the GUI's displays are updated each timestep, as are various inspectors.  If you want items to be performed in a certain order <i>within a timestep</i>, an ordering is the easy way to do it.

<p>You could achieve a similar effect using the classes <tt>sim.engine.<b>Sequence</b></tt> and <tt>sim.engine.<b>RandomSequence</b></tt>, which we'll get to in Tutorial 5.

<p><table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>What goes at Order 1?</b>
<p>Patience, grasshopper, patience.</font></td></tr></table>
We'll schedule the Decreaser to happen at every time step as well, starting at the Epoch, -- but at Order 2 (so it happens after the Particles do their thing):

<p>We finish with <b>main()</b> introduced at the end of tutorial 2.  Note the change in class.

<pre><tt>
    public static void main(String[] args)
        {
        doLoop(Tutorial3.class, args);
        System.exit(0);
        }
        
    }
</tt></pre>

<p>Save the file.

<h2>Create our Particle</h2>

<p>Now we'll write the Particle agent.  Create a file called <b>Particle.java</b>, and in it, add:

<pre><tt>
package sim.app.tutorial3;
import sim.engine.*;
import sim.util.*;

public class Particle implements Steppable
    {
    private static final long serialVersionUID = 1;

    public boolean randomize = false;
    public int xdir;  <font color=gray>// -1, 0, or 1</font>
    public int ydir;  <font color=gray>// -1, 0, or 1</font>
    
    public Particle(int xdir, int ydir)
        {
        this.xdir = xdir;
        this.ydir = ydir;
        }
</tt></pre>

<p>The particle will behave as follows.  If it hits a wall, it "bounces" off the wall.  If it lands on another particle, all particles at that location will have their direction randomized.  The randomization happens by setting their <tt>randomize</tt> flags, and next time they're stepped, the Particles will randomize their own directions if necessary.  The first thing we need to do is get the current position of the Particle.  We could have stored that in the Particle itself, but it's easy enough to just use the location it was set to in the SparseGrid2D:

<pre><tt>
    public void step(SimState state)
        {
        Tutorial3 tut = (Tutorial3)state;
        Int2D location = tut.particles.getObjectLocation(this);
</tt></pre>

<p>Now we leave a trail in the DoubleGrid2D at our location, and randomize direction if needed

<pre><tt>
        <font color=gray>// leave a trail</font>
        tut.trails.field[location.x][location.y] = 1.0;
        
        <font color=gray>// Randomize my direction if requested</font>
        if (randomize)
            {
            xdir = tut.random.nextInt(3) - 1;
            ydir = tut.random.nextInt(3) - 1;
            randomize = false;
            }
</tt></pre>
        
<p>Now we move and check to see if we hit a wall...
<pre><tt>
        <font color=gray>// move</font>
        int newx = location.x + xdir;
        int newy = location.y + ydir;
        
        <font color=gray>// reverse course if hitting boundary</font>
        if (newx &lt; 0) { newx++; xdir = -xdir; }
        else if (newx >= tut.trails.getWidth()) {newx--; xdir = -xdir; }
        if (newy &lt; 0) { newy++ ; ydir = -ydir; }
        else if (newy >= tut.trails.getHeight()) {newy--; ydir = -ydir; }
</tt></pre>

<p>Now store our new location in the SparseGrid2D.

<pre><tt>
        <font color=gray>// set my new location</font>
        Int2D newloc = new Int2D(newx,newy);
        tut.particles.setObjectLocation(this,newloc);
</tt></pre>

<p>Last, get all the objects at our new location out of the SparseGrid2D and set their <tt>randomize</tt> flags.        

<pre><tt>
        <font color=gray>// randomize everyone at that location if need be</font>
        Bag p = tut.particles.getObjectsAtLocation(newloc);
        if (p.numObjs > 1)
            {
            for(int x=0;x &lt; p.numObjs;x++)
                ((Particle)(p.objs[x])).randomize = true;
            }
        }
    }
</tt></pre>

<table width="25%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>Bags are only for Objects?</b>
<p>Yes.  But we also provide extensible arrays for integers (<b>IntBag</b>) and doubles (<b>DoubleBag</b>) as well.  They have nearly identical functionality to Bags.</font></td></tr></table>
<p>We just used a Bag for the first time.  A <b>sim.util.Bag</b> is a wrapper for an array, like an ArrayList or a Vector.  The difference is that Bags have explicitly public, modifiable underlying arrays.  Specifically, Bags have an array of Objects called <tt>objs</tt>, and a count of objects called <tt>numObjs</tt>.  The objects stored in a Bag run from position <tt>0</tt> through <tt>numObjs-1</tt> in the <tt>objs</tt> array (<tt>objs</tt> can be longer than is actually used to store the objects).  Bags also have a special fast <b>remove</b> function which doesn't guarantee maintaining order.  The result is that Bags are significantly (over 3 times) faster than ArrayLists or Vectors.

<p>Save the file.

<h2>Add A Simple Visualizer</h2>

<p>Now we'll write the Particle agent.  Create a file called <b>Tutorial3WithUI.java</b>.  We begin by adding lots of stuff you've already seen before -- except we're specifying a </b>SparseGridPortrayal2D</b> to draw our SparseGrid2D, and we're specifying a <b>FastValueGridPortrayal2D</b> to draw our <b>DoubleGrid2D</b> (various ValueGridPortrayal2Ds can draw either DoubleGrid2D or IntGrid2D).  To the file, add:

<pre><tt>
package sim.app.tutorial3;
import sim.engine.*;
import sim.display.*;
import sim.portrayal.grid.*;
import sim.portrayal.*;
import java.awt.*;
import javax.swing.*;

public class Tutorial3WithUI extends GUIState
    {
    public Display2D display;
    public JFrame displayFrame;

    SparseGridPortrayal2D particlesPortrayal = new SparseGridPortrayal2D();
    FastValueGridPortrayal2D trailsPortrayal = new FastValueGridPortrayal2D("Trail");

    public static void main(String[] args)
        {
        new Tutorial3WithUI().createController();
        }
    
    public Tutorial3WithUI() { super(new Tutorial3(System.currentTimeMillis())); }
    
    public Tutorial3WithUI(SimState state) { super(state); }
    
    public static String getName() { return "Tutorial3: Particles"; }
    
    public static Object getInfo()
        {
        return "&lt;H2>Tutorial3&lt;/H2>&lt;p>An odd little particle-interaction example.";
        }
    
    public void quit()
        {
        super.quit();
        
        if (displayFrame!=null) displayFrame.dispose();
        displayFrame = null;  <font color=gray>// let gc</font>
        display = null;       <font color=gray>// let gc</font>
        }

    public void start()
        {
        super.start();
        setupPortrayals();
        <font color=gray>// this time, we'll call display.reset() and display.repaint() in setupPortrayals()</font>
        }
    
    public void load(SimState state)
        {
        super.load(state);
        setupPortrayals();
        <font color=gray>// likewise...</font>
        }
</tt></pre>

<p><table width="35%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>Why not from range Transparent Clear to Opaque White?</b>
<p>Don't do this unless you need to for your problem.  FastValueGridPortrayal2D can draw grids in two ways: either by drawing lots of rectangles, or by poking a bitmap and stretching the bitmap to fit the area.

<p>The problem is that in Windows and X Windows, the first method is the fastest when your colors are all opaque, but the <i>slowest</i> by far if the colors are transparent -- except for 100% transparent regions, which the simulator avoids drawing at all (fast!).  But the second method consumes more memory and generally only runs well if you increase your heap size to something bigger than normal (see the <b>sim.portrayal.grid.FastValueGridPortrayal2D</b> documentation), so Windows and X Windows by default use the first method.

<p>MacOS X's default is to always use the bitmap (MacOS X is handles bitmaps much more efficiently), except when writing to a movie or to a snapshot (see the documentation).  On MacOS X, you'll likely never need to deviate from the defaults.

<p>You can specify which method to use by calling setBuffering(...); but it's not really necessary as the user can stipulate the method to use in the 2D Options panel as well.

</font></td></tr></table>

Now let's set up our trails portrayal, this time using the <b>setMap</b> method to state that values from 0.0 to 1.0 should range from black to white -- and values outside these bounds will round to either black or white.

<pre><tt>
    public void setupPortrayals()
        {
        <font color=gray>// tell the portrayals what to
        // portray and how to portray them</font>
        trailsPortrayal.setField(
        	((Tutorial3)state).trails);
        trailsPortrayal.setMap(
	        new sim.util.gui.SimpleColorMap(
		    	0.0,1.0,Color.black,Color.white));
</tt></pre>

<p>So far you've only seen FastValueGridPortrayal2Ds.  These are very basic portrayals which always draw their underlying doubles as squares of a given color.  But that's not the general mechanism for the simulator.  Instead, various Field Portrayals usually draw their underlying objects by looking up the proper <b>SimplePortrayal</b> registered for that object, and asking it to draw the object on-screen.  The procedure for looking up the proper SimplePortrayal is used is as follows:

<ol>
<li>
If there is a portrayalForAll, use that.
<li>
Else if the object itself implements the appropriate Portrayal interface, use the object as its own Portrayal.
<li>
Else if a portrayal is registered for the object, use that portrayal.  Portrayals may be registered for <tt>null</tt> as well.
<li>
Else if the object is null:
<ol>
    <li>Use the portrayalForNull if one has been set.
    <li>Else use the defaultNullPortrayal (often a gray circle).
</ol>
<li> 
Else if a Portrayal is registered for the object's exact class (superclasses are ignored), use that.
<li>
Else return the portrayalForRemainder if one has been set.
<li>
Else return the defaultPortrayal (often a gray circle).
</ol>

<table width="35%" align=right valign=top bgcolor="#DDDDDD"><tr><td><font size="1">
<b>What other SimplePortrayals are there?</b>
<p>RectanglePortrayal2D, HexagonalPortrayal2D, and ImagePortrayal2D come to mind.  It's easy to make your own Portrayals as well.</font></td></tr></table>
<p>For now, we use the <b>setPortrayalForAll</b> method to specify that <i>all</i> objects stored in the SparseGrid2D should be portrayed with the same Simple Portrayal.   The SimplePortrayal we pick is a green <b>OvalPortrayal2D</b>.

<pre></tt>
        particlesPortrayal.setField(((Tutorial3)state).particles);
        particlesPortrayal.setPortrayalForAll(
            new sim.portrayal.simple.OvalPortrayal2D(Color.green) );
                   
        <font color=gray>// reschedule the displayer</font>
        display.reset();
                
        <font color=gray>// redraw the display</font>
        display.repaint();
        }
</tt></pre>

<p>Last, we need to build the display and add the field portrayals to it.  First, add stuff you've seen before:

<pre><tt>
    public void init(Controller c)
        {
        super.init(c);
        display = new Display2D(400,400,this);
        displayFrame = display.createFrame();
        c.registerFrame(displayFrame);
        displayFrame.setVisible(true);
        display.setBackdrop(Color.black);
</tt></pre>

<p>Now we attach the field portrayals.  The display will draw the portrayals on top of each other.  The order of drawing is the same as the order of attachment.  We want the trails to be drawn first, then the particles drawn on top of them.  Display2D has a menu option that lets you selectively turn on or off the drawing of these objects -- the names of the menus should be "Trails" and "Particles".  Thus we write:

<pre><tt>
        display.attach(trailsPortrayal,"Trails");
        display.attach(particlesPortrayal,"Particles");
        }
    }
</tt></pre>    

<h2>Run that Puppy</h2>

<p>Save the file.  Compile all three java files.  Run the java code as <tt><b>java sim.app.tutorial3.Tutorial3WithUI</b></tt>.  You should be able to see agents bouncing around and leaving trails!  The Layers menu (the icon at the top-left corner of the Display2D) lets you turn on or off either of the two layers.

<h2>About Serialized Versioning</h2>

<p>The simulator relies on Java's Serialization facility to do its checkpointing.  Serialization writes objects, and all objects they point to (and so on) out to a stream automatically if you obey a few rules.  If you don't obey the rules, you may get an exception such as a NotSerializableException.

<h3>Basic Rules</h3>
<ul>
<li>All classes, except for anonymous classes, should be declared to extend the interface <b>Serializable</b>.
<li>Anonymous classes must subclass from a Serializable class.
<li>All inner classes, including anonymous classes, must be declared inside an outer class which is Serializable,
or are declared inside other inner classes which obey this rule.  (Ultimately the outermost class must be Serializable).
<li>It's good style to declare a serialVerUID for each serializable class (and anonymous classes).
</ul>

<h3>Note</h3>

<p>Sometimes when checkpointing you might get a ClassNotFoundException perhaps.  There's one last possibility: <b>the compilers are <i>naming your inner classes differently</i></b>.  This isn't very common, but it's a definite possibility, and unfortunately there's no way around it.  If this occurs, your only recourse is to use the same compiler and just move your .class files over to the other machine.

<br>
<br>
<br>
<br>
